package com.seek.inter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.seek.authcheck.constants.AuthConstant;
import com.seek.authcheck.constants.AuthProductEnum;
import com.seek.cache.CacheUtil;
import com.seek.common.handler.SpringContextHolder;
import com.seek.constants.ApiParamsConstant;
import com.seek.constants.RedisCustomerConstant;
import com.seek.inter.interdto.InterDtoCUser;
import com.seek.model.dto.ResultInfo;
import com.seek.model.entity.TBizFlow;
import com.seek.service.BaseAuthCheckService;
import com.seek.service.BizFlowService;
import com.seek.service.CustomerService;
import com.seek.util.CommonUtil;
import com.seek.util.DateUtil;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * 外部调用记录流水相关接口
 * Created by weh on 2017/7/4.
 */
public class BizFlowInter {

  private static Logger logger = LoggerFactory.getLogger(BizFlowInter.class);

  private BizFlowService bizFlowService = (BizFlowService) SpringContextHolder
      .getBean("bizFlowService");

  private CustomerService customerService = (CustomerService) SpringContextHolder
      .getBean("customerService");

  /**
   * 创建调用流水
   */
  public ResultInfo createBizFlow(HttpServletRequest request, JSONObject reqJson) throws Exception {
    ResultInfo result = new ResultInfo();

    String productCode = reqJson.getString(ApiParamsConstant.PRODUCT_CODE);
    AuthProductEnum authProductEnum = AuthProductEnum.getAuthProductByProcuctCode(productCode);

    if (null == authProductEnum) {
      result.setStatus(1);
      result.setMessage("产品编码不存在，请检查！");
      return result;
    }

    String token = reqJson.getString(ApiParamsConstant.TOKEN);
    String companyId = reqJson.getString(ApiParamsConstant.COMPANY_ID);
    String orgCode = reqJson.getString(ApiParamsConstant.ORG_CODE);

    Long custId = CommonUtil.getLongValue(reqJson.getString(ApiParamsConstant.CUST_ID));

    Date curDate = new Date();

    String key =
        companyId + "#" + DateUtil.getFormattedDate(curDate, DateUtil.DATE_FORMAT_SHORT_YMD);

    String value = CacheUtil.getRedisData(key);

    if (StringUtils.isEmpty(value)) {
      //如果获取缓存自增value失败,设置成 1，理论上，及时value相同，只要时间戳等参数不同，不存在流水号重复
      value = "1";
      CacheUtil.putRedisDataEx(key, value, ApiParamsConstant.REDIS_EXPIRE_TIME);

    } else {
      if (Long.valueOf(value) >= 99999) {
        value = "1";
        CacheUtil.putRedisData(key, value);
      }
    }

    CacheUtil.incr(key);
    String cid = "0000" + companyId;
    String val = "00000" + value;

    /**流水号生成规则（28位）: S+4位产品编码+4位商户编码(补全4位)+14位时间戳(yyyyMMddHHmmss)+5位随机数**/

    String bizNo = "S" + authProductEnum.getBizCode() + StringUtils
        .substring(cid, cid.length() - 4, cid.length()) + DateUtil
        .getFormattedDate(curDate, DateUtil.DATE_FORMAT_SHORT_YMDHMS) + StringUtils
        .substring(val, val.length() - 5, val.length());
    TBizFlow bizFlow = new TBizFlow();
    bizFlow.setBizNo(bizNo);
    bizFlow.setCompanyId(CommonUtil.getLongValue(companyId));
    bizFlow.setCustomerId(custId);
    bizFlow.setBizType(productCode);
    bizFlow.setOrgCode(orgCode);
    bizFlow.setStatus("");
    bizFlow.setDeleted(0);
    bizFlow.setCreateTime(new Date());
    bizFlow.setModifyTime(bizFlow.getCreateTime());
    bizFlowService.save(bizFlow);
    //更新客户基本信息认证状态(认证中)
    List<String> columnAndProp = getColumnAndProp(productCode);
    String updateColumn = columnAndProp.get(0);
    String sql = "update t_customer set " + updateColumn + " = ? where id = ? and company_id = ?";
    customerService.executeUpdate(sql,
        new Object[]{AuthConstant.AUTH_PROCESS, bizFlow.getCustomerId(), bizFlow.getCompanyId()});

    if (authProductEnum == AuthProductEnum.CERTCARD) {
      String locationCity = reqJson.getString(ApiParamsConstant.GPS_CITY);
      String locationAddress = reqJson.getString(ApiParamsConstant.GPS_ADDR);
      if (StringUtils.isNotEmpty(locationCity) || StringUtils.isNotEmpty(locationAddress)) {
        JSONObject gpsJson = new JSONObject();
        gpsJson.put(ApiParamsConstant.GPS_CITY, locationCity);
        gpsJson.put(ApiParamsConstant.GPS_ADDR, locationAddress);
        CacheUtil.putRedisDataEx("GPS#" + bizNo, JSON.toJSONString(gpsJson),
            ApiParamsConstant.REDIS_EXPIRE_TIME);

      }
    }

    Map<String, Object> cacheData = new HashMap<>();
    cacheData.put(columnAndProp.get(1), AuthConstant.AUTH_PROCESS);
    CacheUtil.refreshCustRedis(token, cacheData);

    result.setStatus(0);
    result.setMessage("成功");
    Map<String, String> map = new HashMap<>();
    map.put(ApiParamsConstant.BIZ_NO, bizNo);
    result.setBody(map);
    return result;
  }

  /**
   * 取消认证,删除流水
   *
   * operate : drop--删除流水 select--查询认证 update--更新任务流水
   */
  public ResultInfo dropBizFlow(HttpServletRequest request, JSONObject reqJson) throws Exception {
    ResultInfo result = new ResultInfo();

    String token = reqJson.getString(ApiParamsConstant.TOKEN);
    String companyId = reqJson.getString(ApiParamsConstant.COMPANY_ID);
    String bizNo = reqJson.getString(ApiParamsConstant.BIZ_NO);
    Long custId = CommonUtil.getLongValue(reqJson.getString(ApiParamsConstant.CUST_ID));
    String operate =
        StringUtils.isNotEmpty(reqJson.getString("operate")) ? reqJson.getString("operate")
            : "select";

    //取消认证
    if (StringUtils.equals("drop", operate)) {
      if (StringUtils.isNotEmpty(bizNo)) {
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("bizNo", bizNo);
        queryMap.put("deleted", 0);
        List<TBizFlow> bizFlows = bizFlowService.getBizFlowByParams(queryMap);
        if (CollectionUtils.isNotEmpty(bizFlows) && bizFlows.size() == 1) {
          TBizFlow bizFlow = bizFlows.get(0);
          if (StringUtils.equals(bizFlow.getStatus(), "1")) {
            result.setStatus(1);
            result.setMessage("业务已执行成功，无法取消！");
            return result;
          } else {
            List<String> columnAndProp = getColumnAndProp(bizFlow.getBizType());
            String updateColumn = columnAndProp.get(0);
            bizFlowService.executeUpdate("delete from t_biz_flow where biz_no = ?",
                new Object[]{bizNo});
            String updateCustSql =
                "update t_customer set " + updateColumn
                    + " = ? where id = ? and company_id = ? and "
                    + updateColumn + " = ?";
            customerService.executeUpdate(updateCustSql,
                new Object[]{0, CommonUtil.getLongValue(custId), CommonUtil.getLongValue(companyId),
                    1});

            Map<String, Object> cacheData = new HashMap<>();
            cacheData.put(columnAndProp.get(1), AuthConstant.AUTH_NONE);
            CacheUtil.refreshCustRedis(token, cacheData);
            CacheUtil.delRedisData("GPS#" + bizNo);
          }
        }
      }
    } else if (StringUtils.equals("update", operate)) {
      //更新流水状态
      String orgBizNo = reqJson.getString(ApiParamsConstant.ORG_BIZ_NO);
      if (StringUtils.isNotEmpty(orgBizNo) && StringUtils.isNotEmpty(bizNo)) {
        bizFlowService.updateBizFlow(
            "update t_biz_flow set org_biz_no = ? ,modify_time= now() where biz_no = ?", orgBizNo,
            bizNo);

        String noticeJson = CacheUtil
            .getRedisData(RedisCustomerConstant.TASK_KEY_PREFIX + orgBizNo);
        if (StringUtils.isNotEmpty(noticeJson)) {
          //如果第三方回调发生在请求之前，则需要触发处理认证
          Map<String, Object> queryMap = new HashMap<>();
          queryMap.put("bizNo", bizNo);
          queryMap.put("deleted", 0);
          List<TBizFlow> bizFlows = bizFlowService.getBizFlowByParams(queryMap);
          if (CollectionUtils.isNotEmpty(bizFlows) && bizFlows.size() == 1) {
            AuthProductEnum productEnum = AuthProductEnum
                .getAuthProductByProcuctCode(bizFlows.get(0).getBizType());
            if (null != productEnum) {
              BaseAuthCheckService authCheckService = SpringContextHolder
                  .getBean(productEnum.getCheckBeanName());
              authCheckService.autoCheck(JSON.parseObject(noticeJson));
            }
          }
        }
      }

    }

    CustomerInter customerInter = new CustomerInter();
    result = customerInter.getCustAuthInfo(request, reqJson);
    logger.info("认证数据:{}", JSON.toJSONString(result.getBody()));

    return result;
  }

  /**
   * 根据productCode获取需要更新的字段和user对象需要更新的属性
   */
  private static List<String> getColumnAndProp(String productCode) {
    List<String> result = new ArrayList<>();
    String column = "";
    String prop = "";
    switch (productCode) {
      case "certcard":
        column = "certification_status";
        prop = "certificationStatus";
        break;
      case "carrier":
        column = "mobile_status";
        prop = "mobileStatus";
        break;
      case "alipay":
        column = "zfb_status";
        prop = "zfbStatus";
        break;

      default:
        column = "";
        prop = "";
        break;
    }
    result.add(column);
    result.add(prop);
    return result;
  }

}
